package etm.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;

import upc.condominio.modelo.Cuota;
import upc.condominio.modelo.CuotaConcepto;
import upc.condominio.util.ConexionBD;
import etm.excepcion.DAOExcepcion;

public class RegistroCuotasDAO extends BaseDAO {

	public Collection<Cuota> listarxPeriodo(int idUbicacion, String periodo) throws DAOExcepcion {
		System.out.println("RegistroCuotasDAO: listar()");
		Collection<Cuota> c = new ArrayList<Cuota>();
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		SimpleDateFormat sdf= new SimpleDateFormat("dd/MM/yyyy");
		try {
			con = ConexionBD.obtenerConexion();
			String query = "SELECT v.idVivienda,v.idUbicacion,u.descripcion,v.numero,v.TipoVivienda, " +
							" v.idResidente ,r.nombres,r.ApellidoPaterno,r.apellidoMaterno," +
							" IFNULL(c.importe,0) as importe,IFNULL(c.saldo,0) as saldo,c.fechaVencimiento, IFNULL(periodo,'') as periodo,IFNULL(c.idCuota,0) as idCuota" +
							" from vivienda v " +
							" inner join residente r on r.idResidente=v.idResidente" +
							" inner join ubicacion u on u.idUbicacion= v.idUbicacion " +
							" left join cuota c on r.idResidente=c.idResidente" +
							" 				and c.periodo=? " +
							" WHERE  v.idUbicacion = ? ";
			
			stmt = con.prepareStatement(query);
			stmt.setString(1, periodo);
			stmt.setInt(2, idUbicacion);
			rs = stmt.executeQuery();
			while (rs.next()) {
				Cuota vo = new Cuota();			
				vo.setIdCuota(rs.getInt("idCuota"));
				vo.getVivienda().setIdVivienda(rs.getString("idVivienda"));
				vo.getVivienda().getUbicacionVivienda().setIdUbicacion(rs.getInt("idUbicacion"));
				vo.getVivienda().getUbicacionVivienda().setDescripcion(rs.getString("descripcion"));
				vo.getVivienda().setNumero(rs.getString("numero"));
				vo.getVivienda().getTipoVivienda().setIdTipo(rs.getString("TipoVivienda"));
				vo.getVivienda().getTipoVivienda().setDescripcion(rs.getString("TipoVivienda"));
				vo.getVivienda().getResidente().setIdResidente(rs.getInt("idResidente"));
				vo.getVivienda().getResidente().setNombres(rs.getString("nombres"));
				vo.getVivienda().getResidente().setApePaterno(rs.getString("apellidoPaterno"));
				vo.getVivienda().getResidente().setApeMaterno(rs.getString("apellidoMaterno"));	
				vo.setImporte(rs.getDouble("importe"));
				vo.setSaldo(rs.getDouble("saldo"));
				vo.setPeriodo(rs.getString("periodo"));
				
				if (rs.getDate("fechaVencimiento")!=null){
					vo.setFechaVenc(rs.getDate("fechaVencimiento"));					
				}
				
				c.add(vo);
			}
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return c;
	}
	
	public Collection<Cuota> listarxPeriodoResidente(int idResidente,int idUbicacion, String periodo) throws DAOExcepcion {
		System.out.println("RegistroCuotasDAO: listarxPeriodoResidente()");
		Collection<Cuota> c = new ArrayList<Cuota>();
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		SimpleDateFormat sdf= new SimpleDateFormat("dd/MM/yyyy");
		try {
			con = ConexionBD.obtenerConexion();
			String query = "SELECT v.idVivienda,v.idUbicacion,u.descripcion,v.numero,v.TipoVivienda, " +
							" v.idResidente ,r.nombres,r.ApellidoPaterno,r.apellidoMaterno," +
							" IFNULL(c.importe,0) as importe,IFNULL(c.saldo,0) as saldo,c.fechaVencimiento, IFNULL(periodo,'') as periodo," +
							" IFNULL(cc.importe,0) as importeCC,cp.descripcion as descripPago" +
							" from vivienda v " +
							" inner join residente r on r.idResidente=v.idResidente" +
							" inner join ubicacion u on u.idUbicacion= v.idUbicacion " +
							" INNER join cuota c on r.idResidente=c.idResidente" +
							" inner join cuotaConcepto cc on cc.idCuota= c.idCuota" +
							" inner join conceptoPago cp on cp.idConceptoPago=cc.idConceptoPago" +
							" WHERE r.idResidente=? AND v.idUbicacion = ?  and c.periodo=? ";
			
			stmt = con.prepareStatement(query);
			stmt.setInt(1, idResidente);
			stmt.setInt(2, idUbicacion);
			stmt.setString(3, periodo);
			
			rs = stmt.executeQuery();
			while (rs.next()) {
				Cuota vo = new Cuota();				
				vo.getVivienda().setIdVivienda(rs.getString("idVivienda"));
				vo.getVivienda().getUbicacionVivienda().setIdUbicacion(rs.getInt("idUbicacion"));
				vo.getVivienda().getUbicacionVivienda().setDescripcion(rs.getString("descripcion"));
				vo.getVivienda().setNumero(rs.getString("numero"));
				vo.getVivienda().getTipoVivienda().setIdTipo(rs.getString("TipoVivienda"));
				vo.getVivienda().getTipoVivienda().setDescripcion(rs.getString("TipoVivienda"));
				vo.getVivienda().getResidente().setIdResidente(rs.getInt("idResidente"));
				vo.getVivienda().getResidente().setNombres(rs.getString("nombres"));
				vo.getVivienda().getResidente().setApePaterno(rs.getString("apellidoPaterno"));
				vo.getVivienda().getResidente().setApeMaterno(rs.getString("apellidoMaterno"));	
				vo.setImporte(rs.getDouble("importe"));
				vo.setSaldo(rs.getDouble("saldo"));
				vo.setPeriodo(rs.getString("periodo"));
				
				if (rs.getDate("fechaVencimiento")!=null){
					vo.setFechaVenc(rs.getDate("fechaVencimiento"));					
				}
				
				c.add(vo);
			}
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return c;
	}
	
	public Cuota listarConceptosxResidente(int idCuota) throws DAOExcepcion {
		System.out.println("RegistroCuotasDAO: listarConceptosxResidente()");
		//Collection<Cuota> c = new ArrayList<Cuota>();
		Cuota c= new Cuota();
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		SimpleDateFormat sdf= new SimpleDateFormat("dd/MM/yyyy");
		try {
			con = ConexionBD.obtenerConexion();
			String query = "select cp.idConceptoPago,cp.descripcion as descripPago,IFNULL(cc.importe,0) as importeCC,"+
			" cc.idCuotaConcepto,IF(c.importe=c.saldo,'Pendiente','Pagado') as estado,'Registrado' as flag, c.idVivienda, c.idCuota "+
			" from cuotaConcepto cc"+
			" Inner Join cuota c on cc.idCuota=c.idCuota"+
			" Inner join conceptoPago cp on cp.idConceptoPago=cc.idConceptoPago"+
			" WHERE c.idCuota=? ";
			
			stmt = con.prepareStatement(query);
			stmt.setInt(1, idCuota);
			
			rs = stmt.executeQuery();
			while (rs.next()) {
				CuotaConcepto vo = new CuotaConcepto();			
				vo.setIdCuotaConcepto(rs.getInt("idCuotaConcepto"));
				vo.getConceptoPago().setIdConcepto(rs.getInt("idConceptoPago"));
				vo.getConceptoPago().setDescripcion(rs.getString("descripPago"));
				c.setEstado(rs.getString("estado"));
				vo.setEstado(rs.getString("estado"));
				vo.setImporte(rs.getDouble("importeCC"));				
				vo.setFlag(rs.getString("flag"));
				c.getVivienda().setIdVivienda(rs.getString("idVivienda"));
				c.setIdCuota(rs.getInt("idCuota"));
				c.getLstCuotaConceptosNuevos().add(vo);
			}
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return c;
	}
	public Cuota obtener(int idCuota) throws DAOExcepcion {
		Cuota cuota = new Cuota();
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			String query = "select idVivienda,idResidente,Periodo,Importe,Saldo,FechaVencimiento "+
							"from Cuota where idCuota=?";
			con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(query);
			stmt.setInt(1, idCuota);
			rs = stmt.executeQuery();
			if (rs.next()) {
				cuota.setIdCuota(idCuota);
				ViviendaDAO daoVivienda = new ViviendaDAO();				
				cuota.setVivienda(daoVivienda.buscarPorID(rs.getInt(1)));
				ResidenteDAO daoResidente= new ResidenteDAO();
				cuota.setResidente(daoResidente.buscarporId(rs.getInt(2)));
				cuota.setPeriodo(rs.getString(3));
				cuota.setImporte(rs.getDouble(4));
				cuota.setSaldo(rs.getDouble(5));
				cuota.setFechaVenc(rs.getDate(6));
				
			}
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return cuota;
	}
	
	
	
	public Cuota actualizarSaldo(int idCuota, double importe, int operacion) throws DAOExcepcion {
		Cuota cuota = new Cuota();
		Connection con = null;
		PreparedStatement stmt = null;		
		try {
			String query = "update Cuota set saldo=saldo+("+importe+"*("+operacion+")) where idCuota=?";
							
			con = ConexionBD.obtenerConexion();
			stmt = con.prepareStatement(query);
			stmt.setInt(1, idCuota);
			int i = stmt.executeUpdate();
			if (i != 1) {
				throw new SQLException("No se pudo actualizar");
			}			
			cuota=obtener(idCuota);
					
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {			
			this.cerrarStatement(stmt);
			this.cerrarConexion(con);
		}
		return cuota;
	}
	
	/**
	 * 
	 * @param cuota
	 * @throws DAOExcepcion
	 */
	public void grabarCuota(Cuota cuota) throws DAOExcepcion {
		Connection con = null;
		
		try {
			con = ConexionBD.obtenerConexion();
			con.setAutoCommit(false);
		

			Cuota c= this.insertCuota(cuota,con);
			System.out.println("se inserto cuota " + c.getIdCuota());
			this.insertConcepto(c,con);
			
			con.commit();
			con.setAutoCommit(true);	
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			try {
				con.rollback();
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			throw new DAOExcepcion(e.getMessage());
		}finally{
			this.cerrarConexion(con);
		}
		
	}
	
	private Cuota insertCuota(Cuota cuota,Connection con) throws DAOExcepcion {
		
		System.out.println("Inserto Cuota");
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			String query = "insert into cuota (idVivienda,idResidente,periodo,importe,saldo,fechaVencimiento) "+
					 " values(?,?,?,?,?,now())";
				
			stmt = con.prepareStatement(query);
			stmt.setInt(1, Integer.parseInt(cuota.getVivienda().getIdVivienda()));
			stmt.setInt(2, cuota.getVivienda().getResidente().getIdResidente());		
			stmt.setString(3, cuota.getPeriodo());
			stmt.setDouble(4, cuota.getImporte());
			stmt.setDouble(5, cuota.getSaldo());
			int i = stmt.executeUpdate();
			if (i != 1) {
				throw new SQLException("No se pudo insertar");
			}
			// Obtener el ultimo id
			int id = 0;
			query = "select last_insert_id()";
			stmt = con.prepareStatement(query);
			rs = stmt.executeQuery();
			if (rs.next()) {
				id = rs.getInt(1);
			}
			cuota.setIdCuota(id);
			System.out.println("Inserto Cuota OK");
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);			
		}
		return cuota;
	}
	
	/**
	 * 
	 * @param cuota
	 * @throws DAOExcepcion
	 */
	public void grabaEliminaConcepto(Cuota cuota) throws DAOExcepcion {
		Connection con = null;
		
		try {
			con = ConexionBD.obtenerConexion();
			con.setAutoCommit(false);
			
			this.insertConcepto(cuota,con);
			this.deleteConcepto(cuota,con);
			
			con.commit();
			con.setAutoCommit(true);	
			
		} catch (SQLException e) {
			System.err.println(e.getMessage());
			try {
				con.rollback();
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			throw new DAOExcepcion(e.getMessage());
		}finally{
			this.cerrarConexion(con);
		}
	}
	
	private Cuota insertConcepto(Cuota cuota,Connection con) throws DAOExcepcion {
		System.out.println("Inserta Cuota concepto");
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			String query = "insert cuotaConcepto (idCuota,idConceptoPago,importe) "+
					 " values(?,?,?)";
			
			
			stmt = con.prepareStatement(query);
			
			for (CuotaConcepto c: cuota.getLstCuotaConceptosNuevos()){
				if(c.getIdCuotaConcepto()==0){
					System.out.println("DAO c.getIdCuotaConcepto()=0 " + cuota.getIdCuota() + "  "+c.getConceptoPago().getIdConcepto());
					stmt.setInt(1, cuota.getIdCuota());
					stmt.setInt(2, c.getConceptoPago().getIdConcepto());		
					stmt.setDouble(3, c.getImporte());
					
					int i = stmt.executeUpdate();
					if (i != 1) {
						throw new SQLException("No se pudo insertar concepto");
					}	
				}
			}
			System.out.println("Inserta Cuota concepto OK");
		} catch (SQLException e) {
			System.err.println(e.getMessage());	       
			throw new DAOExcepcion(e.getMessage());
		} finally {
			this.cerrarResultSet(rs);
			this.cerrarStatement(stmt);
			
		}
		return cuota;
	}
	
	private Cuota deleteConcepto(Cuota cuota,Connection con) throws DAOExcepcion {
		
		PreparedStatement stmt = null;
		
		try {
			String query = "delete from cuotaConcepto Where idCuotaConcepto=?";
						
			stmt = con.prepareStatement(query);
			
			for (CuotaConcepto c: cuota.getLstCuotaConceptosEliminar()){
				stmt.setInt(1, c.getIdCuotaConcepto());
				
				int i = stmt.executeUpdate();
				if (i != 1) {
					throw new SQLException("No se pudo eliminar concepto");
				}	
			}
			
		} catch (SQLException e) {
			System.err.println(e.getMessage());
	        
			throw new DAOExcepcion(e.getMessage());
		} finally {
		
			this.cerrarStatement(stmt);
			
		}
		return cuota;
	}

}
